/*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, this software may be distributed under the terms of BSD
* license.
*
*
*
* Authors:                  zhoujian
* Email:            343600434@qq.com
* Date:         Apr-10-2025 15:04:59
*
*/


#include "can.h"
#include "gd32l23x.h"
#include <stdio.h>
#include "gd32l23x_eval.h"
#include "device.h"
#include "input.h"
#include <string.h>
#include "flash.h"


uint8_t send_version;
FlagStatus receive_flag;
can_receive_message_struct receive_message;

void can_params_init(void)
{
    can_parameter_struct can_parameter;
    can_filter_parameter_struct can_filter;
    rcu_periph_clock_enable(RCU_CAN);
    rcu_periph_clock_enable(RCU_GPIOA);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_11);
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_11);
    gpio_af_set(GPIOA, GPIO_AF_8, GPIO_PIN_11);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12);
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_12);
    gpio_af_set(GPIOA, GPIO_AF_8, GPIO_PIN_12);
    nvic_irq_enable(USBD_LP_CAN_RX0_IRQn, 0);
    /* initialize CAN structures */
    can_struct_para_init(CAN_INIT_STRUCT, &can_parameter);
    can_struct_para_init(CAN_FILTER_STRUCT, &can_filter);
    /* initialize CAN register */
    can_deinit();
    /* initialize CAN */
    can_parameter.time_triggered = DISABLE;
    can_parameter.auto_bus_off_recovery = ENABLE;
    can_parameter.auto_wake_up = DISABLE;
    can_parameter.auto_retrans = ENABLE;
    can_parameter.rec_fifo_overwrite = DISABLE;
    can_parameter.trans_fifo_order = DISABLE;
    can_parameter.working_mode = CAN_NORMAL_MODE;
    can_parameter.resync_jump_width = CAN_BT_SJW_1TQ;
    can_parameter.time_segment_1 = CAN_BT_BS1_12TQ;
    can_parameter.time_segment_2 = CAN_BT_BS2_3TQ;
    /* baudrate 1Mbps */
    can_parameter.prescaler = 8;
    can_init(&can_parameter);
    /* initialize filter */
    /* CAN0 filter number */
    can_filter.filter_number = 0;
    /* initialize filter */
    can_filter.filter_mode = CAN_FILTERMODE_MASK;
    can_filter.filter_bits = CAN_FILTERBITS_32BIT;
    can_filter.filter_list_high = 0x0000;
    can_filter.filter_list_low = 0x0000;
    can_filter.filter_mask_high = 0x0000;
    can_filter.filter_mask_low = 0x0000;
    can_filter.filter_fifo_number = CAN_FIFO0;
    can_filter.filter_enable = ENABLE;
    can_filter_init(&can_filter);
    can_interrupt_enable(CAN_INTEN_RFNEIE0);
    receive_flag = RESET;
    log_debug("can init\n");
    check_can_time = CAN_TIMEOUT_TIME_H;
}

can_trasnmit_message_struct transmit_message;

void can_send_data()
{
    uint8_t transmit_mailbox = 0;
    uint8_t i;
    /* initialize transmit message */
    transmit_message.tx_sfid = 0x0;
    transmit_message.tx_efid = 0x18F003A5;
    transmit_message.tx_ft = CAN_FT_DATA;
    transmit_message.tx_ff = CAN_FF_EXTENDED;
    transmit_message.tx_dlen = 8;
    //memcpy(transmit_message.tx_data, &range_info, 8);
    uint16_t trip = flash_info.trip * 10 + flash_info.trip_dam;
    transmit_message.tx_data[0] = (trip >> 8) & 0xFF;
    transmit_message.tx_data[1] = trip & 0xFF;
    transmit_message.tx_data[2] = 0;
    transmit_message.tx_data[3] = 0;
    uint16_t odo = flash_info.odo + (flash_info.mul * 60000);
    transmit_message.tx_data[4] = (odo >> 8) & 0xFF;
    transmit_message.tx_data[5] = (odo) & 0xFF;
    transmit_message.tx_data[6] = flash_info.mul;
    transmit_message.tx_data[7] = range_info.speed;
#if 1
    log_debug("\r\n can0 transmit data:");

    for(i = 0; i < transmit_message.tx_dlen; i++) {
        log_debug(" %02x", transmit_message.tx_data[i]);
    }

    log_debug("  can send\n");
#endif
    /* transmit message */
    transmit_mailbox = can_message_transmit(&transmit_message);
    /* waiting for transmit completed */
    //timeout = 0xFFFF;
    //while((CAN_TRANSMIT_OK != can_transmit_states(transmit_mailbox))) {
    // timeout--;
    //}
}

void can_send_version0()
{
    uint8_t transmit_mailbox = 0;
    uint8_t i;
    /* initialize transmit message */
    transmit_message.tx_sfid = 0x0;
    transmit_message.tx_efid = 0x18FD10A5;
    transmit_message.tx_ft = CAN_FT_DATA;
    transmit_message.tx_ff = CAN_FF_EXTENDED;
    transmit_message.tx_dlen = 8;
    transmit_message.tx_data[0] = 0x40;
    transmit_message.tx_data[1] = (0 << 6) | (0 << 4) | 1;
    transmit_message.tx_data[2] = 250;
    transmit_message.tx_data[3] = 0;
    transmit_message.tx_data[4] = 0;
    transmit_message.tx_data[5] = 0;
    transmit_message.tx_data[6] = 0;
    transmit_message.tx_data[7] = 0;
    log_debug("\r\n can0 v0 transmit data:");

    for(i = 0; i < transmit_message.tx_dlen; i++) {
        log_debug(" %02x", transmit_message.tx_data[i]);
    }

    /* transmit message */
    transmit_mailbox = can_message_transmit(&transmit_message);
    /* waiting for transmit completed */
    //timeout = 0xFFFF;
    //while((CAN_TRANSMIT_OK != can_transmit_states(transmit_mailbox))) {
    // timeout--;
    //}
    log_debug("  can send\n");
}
void can_send_version1()
{
    uint8_t transmit_mailbox = 0;
    uint8_t i;
    /* initialize transmit message */
    transmit_message.tx_sfid = 0x0;
    transmit_message.tx_efid = 0x18F0FDA5;
    transmit_message.tx_ft = CAN_FT_DATA;
    transmit_message.tx_ff = CAN_FF_EXTENDED;
    transmit_message.tx_dlen = 8;
    uint8_t a[11] = __DATE__;
    uint16_t b = (a[7] - 0x30) * 1000 + (a[8] - 0x30) * 100 + (a[9] - 0x30) * 10 + (a[10] - 0x30);
    transmit_message.tx_data[0] = b >> 8;
    transmit_message.tx_data[1] = b & 0xFF;
    uint8_t y;
    y = 0;

    if(a[0] == 'F') {
        y = 2;
        //GUI_ShowChar_2(64 + 8 * 1, 0, '2', 16, 1);

    } else if(a[0] == 'S') {
        y = 9;
        //GUI_ShowChar_2(64 + 8 * 1, 0, '9', 16, 1);

    } else if(a[0] == 'O') {
        y = 10;
        //GUI_ShowChar_2(64 + 8 * 1, 0, 'A', 16, 1);

    } else if(a[0] == 'N') {
        y = 11;
        //GUI_ShowChar_2(64 + 8 * 1, 0, 'B', 16, 1);

    } else if(a[0] == 'D') {
        y = 12;
        //GUI_ShowChar_2(64 + 8 * 1, 0, 'C', 16, 1);

    } else if((a[0] == 'A')) {
        if((a[1] == 'p')) {
            y = 4;
            //GUI_ShowChar_2(64 + 8 * 1, 0, '4', 16, 1);

        } else if((a[1] == 'u')) {
            y = 8;
            //GUI_ShowChar_2(64 + 8 * 1, 0, '8', 16, 1);
        }

    } else if((a[0] == 'M')) {
        if((a[2] == 'r')) {
            y = 3;
            //GUI_ShowChar_2(64 + 8 * 1, 0, '3', 16, 1);

        } else if((a[2] == 'y')) {
            y = 5;
            //GUI_ShowChar_2(64 + 8 * 1, 0, '5', 16, 1);
        }

    } else if((a[0] == 'J')) {
        if((a[1] == 'a')) {
            y = 1;
            //GUI_ShowChar_2(64 + 8 * 1, 0, '1', 16, 1);

        } else if((a[1] == 'u')) {
            if((a[2] == 'n')) {
                y = 6;
                //GUI_ShowChar_2(64 + 8 * 1, 0, '6', 16, 1);

            } else if((a[2] == 'l')) {
                y = 7;
                //GUI_ShowChar_2(64 + 8 * 1, 0, '7', 16, 1);
            }
        }
    }

    transmit_message.tx_data[2] = y;
    transmit_message.tx_data[3] = 0;
    transmit_message.tx_data[4] = 0;
    transmit_message.tx_data[5] = 1;
    transmit_message.tx_data[6] = 0;
    transmit_message.tx_data[7] = 0;
    log_debug("\r\n can0 v1 transmit data:");

    for(i = 0; i < transmit_message.tx_dlen; i++) {
        log_debug(" %02x", transmit_message.tx_data[i]);
    }

    /* transmit message */
    transmit_mailbox = can_message_transmit(&transmit_message);
    /* waiting for transmit completed */
    //timeout = 0xFFFF;
    //while((CAN_TRANSMIT_OK != can_transmit_states(transmit_mailbox))) {
    // timeout--;
    //}
    log_debug("  can send\n");
}


//#define TEST_CAN_LINE
#ifdef TEST_CAN_PROTOCOL

void mcu_out0()//20ms
{
    uint8_t transmit_mailbox = 0;
    uint8_t i;
    /* initialize transmit message */
    transmit_message.tx_sfid = 0x0;
    transmit_message.tx_efid = 0x18F001C1;
    transmit_message.tx_ft = CAN_FT_DATA;
    transmit_message.tx_ff = CAN_FF_EXTENDED;
    transmit_message.tx_dlen = 8;
    uint16_t v = 1000;
    transmit_message.tx_data[0] = (v >> 8) & 0xFF; //20C
    transmit_message.tx_data[1] = v & 0xFF;
    uint16_t a = 300;
    transmit_message.tx_data[2] = (a >> 8) & 0xFF; //0,1,2,3,100
    transmit_message.tx_data[3] = a & 0xFF;
    uint16_t n = 300;
    transmit_message.tx_data[4] = (n >> 8) & 0xFF;
    transmit_message.tx_data[5] = n & 0xFF;
    uint16_t s = 100;
    transmit_message.tx_data[6] = (s >> 8) & 0xFF;
    transmit_message.tx_data[7] = s & 0xFF;
#if 1
    log_debug("\r\n can0 transmit data:");

    for(i = 0; i < transmit_message.tx_dlen; i++) {
        log_debug(" %02x", transmit_message.tx_data[i]);
    }

    log_debug("  can send\n");
#endif
    /* transmit message */
    transmit_mailbox = can_message_transmit(&transmit_message);
    /* waiting for transmit completed */
    uint32_t timeout = 0xFFFF;

    while((CAN_TRANSMIT_OK != can_transmit_states(transmit_mailbox))) {
        timeout--;
    }
}
void mcu_out1_test(uint8_t n)//20ms
{
    uint8_t transmit_mailbox = 0;
    uint8_t i;
    static uint8_t s;
    /* initialize transmit message */
    transmit_message.tx_sfid = 0x0;
    transmit_message.tx_efid = 0x18F002C1;
    transmit_message.tx_ft = CAN_FT_DATA;
    transmit_message.tx_ff = CAN_FF_EXTENDED;
    transmit_message.tx_dlen = 8;
    transmit_message.tx_data[0] = 50 + 20; //20C
    transmit_message.tx_data[1] = 50 + 50;
    transmit_message.tx_data[2] = 1;//0,1,2,3,100
    transmit_message.tx_data[3] = 0;
    transmit_message.tx_data[4] = 0 << 0; //0,3,
    transmit_message.tx_data[5] = n;
    transmit_message.tx_data[6] = 1;
    transmit_message.tx_data[7] = 00;
#if 1
    log_debug("\r\n can0 transmit data:");

    for(i = 0; i < transmit_message.tx_dlen; i++) {
        log_debug(" %02x", transmit_message.tx_data[i]);
    }

    log_debug("  can send\n");
#endif
    /* transmit message */
    transmit_mailbox = can_message_transmit(&transmit_message);
    /* waiting for transmit completed */
    uint32_t timeout = 0xFFFF;

    while((CAN_TRANSMIT_OK != can_transmit_states(transmit_mailbox))) {
        timeout--;
    }
}

void mcu_out1()//20ms
{
    uint8_t transmit_mailbox = 0;
    uint8_t i;
    static uint8_t s;
    /* initialize transmit message */
    transmit_message.tx_sfid = 0x0;
    transmit_message.tx_efid = 0x18F002C1;
    transmit_message.tx_ft = CAN_FT_DATA;
    transmit_message.tx_ff = CAN_FF_EXTENDED;
    transmit_message.tx_dlen = 8;
    transmit_message.tx_data[0] = 50 + 20; //20C
    transmit_message.tx_data[1] = 50 + 50;
    transmit_message.tx_data[2] = 1;//0,1,2,3,100
    transmit_message.tx_data[3] = 0;
    transmit_message.tx_data[4] = 0 << 0; //0,3,
    transmit_message.tx_data[5] = 0;
    transmit_message.tx_data[6] = 1;
    transmit_message.tx_data[7] = 00;
#if 1
    log_debug("\r\n can0 transmit data:");

    for(i = 0; i < transmit_message.tx_dlen; i++) {
        log_debug(" %02x", transmit_message.tx_data[i]);
    }

    log_debug("  can send\n");
#endif
    /* transmit message */
    transmit_mailbox = can_message_transmit(&transmit_message);
    /* waiting for transmit completed */
    uint32_t timeout = 0xFFFF;

    while((CAN_TRANSMIT_OK != can_transmit_states(transmit_mailbox))) {
        timeout--;
    }
}

void yb_clean()
{
    uint8_t transmit_mailbox = 0;
    uint8_t i;
    /* initialize transmit message */
    transmit_message.tx_sfid = 0x0;
    transmit_message.tx_efid = 0x18FE20F1;
    transmit_message.tx_ft = CAN_FT_DATA;
    transmit_message.tx_ff = CAN_FF_EXTENDED;
    transmit_message.tx_dlen = 8;
    transmit_message.tx_data[0] = 0;
    transmit_message.tx_data[1] = 0;
    transmit_message.tx_data[2] = 0;//0,1,2,3,100
    transmit_message.tx_data[3] = 0;
    transmit_message.tx_data[4] = 0;
    transmit_message.tx_data[5] = 0;
    transmit_message.tx_data[6] = 0;
    transmit_message.tx_data[7] = 0;
#if 1
    log_debug("\r\n can0 transmit data:");

    for(i = 0; i < transmit_message.tx_dlen; i++) {
        log_debug(" %02x", transmit_message.tx_data[i]);
    }

    log_debug("  can send\n");
#endif
    /* transmit message */
    transmit_mailbox = can_message_transmit(&transmit_message);
    /* waiting for transmit completed */
    uint32_t timeout = 0xFFFF;

    while((CAN_TRANSMIT_OK != can_transmit_states(transmit_mailbox))) {
        timeout--;
    }
}

void bat_up_status1()//100ms
{
    uint8_t transmit_mailbox = 0;
    uint8_t i;
    /* initialize transmit message */
    transmit_message.tx_sfid = 0x0;
    transmit_message.tx_efid = 0x18F101F4;
    transmit_message.tx_ft = CAN_FT_DATA;
    transmit_message.tx_ff = CAN_FF_EXTENDED;
    transmit_message.tx_dlen = 8;
    uint16_t v = 586;// 586:58.6v
    transmit_message.tx_data[0] = v & 0xFF; //20C
    transmit_message.tx_data[1] = (v >> 8) & 0xFF;
    uint16_t a = 1000;//1000: -500 + 1000 = 500A;
    transmit_message.tx_data[2] = (v) & 0xFF; //0,1,2,3,100
    transmit_message.tx_data[3] = (v >> 8) & 0xFF;
    transmit_message.tx_data[4] = 1 << 1; //1:
    transmit_message.tx_data[5] = 0;//charge
    transmit_message.tx_data[6] = 1;
    transmit_message.tx_data[7] = 00;
#if 1
    log_debug("\r\n can0 transmit data:");

    for(i = 0; i < transmit_message.tx_dlen; i++) {
        log_debug(" %02x", transmit_message.tx_data[i]);
    }

    log_debug("  can send\n");
#endif
    /* transmit message */
    transmit_mailbox = can_message_transmit(&transmit_message);
    /* waiting for transmit completed */
    uint32_t timeout = 0xFFFF;

    while((CAN_TRANSMIT_OK != can_transmit_states(transmit_mailbox))) {
        timeout--;
    }
}
void bat_up_status2()//100ms
{
    uint8_t transmit_mailbox = 0;
    uint8_t i;
    /* initialize transmit message */
    transmit_message.tx_sfid = 0x0;
    transmit_message.tx_efid = 0x18F102F4;
    transmit_message.tx_ft = CAN_FT_DATA;
    transmit_message.tx_ff = CAN_FF_EXTENDED;
    transmit_message.tx_dlen = 8;
    uint16_t soc = 650;// 586:58.6v
    transmit_message.tx_data[0] = soc & 0xFF; //20C
    transmit_message.tx_data[1] = (soc >> 8) & 0xFF;
    uint16_t soh = 654;//1000: -500 + 1000 = 500A;
    transmit_message.tx_data[2] = (soh) & 0xFF; //0,1,2,3,100
    transmit_message.tx_data[3] = (soh >> 8) & 0xFF;
    uint16_t f_cur = 582;// 586:58.6v
    transmit_message.tx_data[4] = f_cur & 0xFF; //20C
    transmit_message.tx_data[5] = (f_cur >> 8) & 0xFF;
    uint16_t b_cur = 582;//1000: -500 + 1000 = 500A;
    transmit_message.tx_data[6] = (b_cur) & 0xFF; //0,1,2,3,100
    transmit_message.tx_data[7] = (b_cur >> 8) & 0xFF;
#if 1
    log_debug("\r\n can0 transmit data:");

    for(i = 0; i < transmit_message.tx_dlen; i++) {
        log_debug(" %02x", transmit_message.tx_data[i]);
    }

    log_debug("  can send\n");
#endif
    /* transmit message */
    transmit_mailbox = can_message_transmit(&transmit_message);
    /* waiting for transmit completed */
    uint32_t timeout = 0xFFFF;

    while((CAN_TRANSMIT_OK != can_transmit_states(transmit_mailbox))) {
        timeout--;
    }
}

void bat_down_status1()//100ms
{
    uint8_t transmit_mailbox = 0;
    uint8_t i;
    /* initialize transmit message */
    transmit_message.tx_sfid = 0x0;
    transmit_message.tx_efid = 0x18F101F5;
    transmit_message.tx_ft = CAN_FT_DATA;
    transmit_message.tx_ff = CAN_FF_EXTENDED;
    transmit_message.tx_dlen = 8;
    uint16_t v = 586;// 586:58.6v
    transmit_message.tx_data[0] = v & 0xFF; //20C
    transmit_message.tx_data[1] = (v >> 8) & 0xFF;
    uint16_t a = 1000;//1000: -500 + 1000 = 500A;
    transmit_message.tx_data[2] = (v) & 0xFF; //0,1,2,3,100
    transmit_message.tx_data[3] = (v >> 8) & 0xFF;
    transmit_message.tx_data[4] = 1 << 1; //1:
    transmit_message.tx_data[5] = 0;//charge
    transmit_message.tx_data[6] = 1;
    transmit_message.tx_data[7] = 00;
#if 1
    log_debug("\r\n can0 transmit data:");

    for(i = 0; i < transmit_message.tx_dlen; i++) {
        log_debug(" %02x", transmit_message.tx_data[i]);
    }

    log_debug("  can send\n");
#endif
    /* transmit message */
    transmit_mailbox = can_message_transmit(&transmit_message);
    /* waiting for transmit completed */
    uint32_t timeout = 0xFFFF;

    while((CAN_TRANSMIT_OK != can_transmit_states(transmit_mailbox))) {
        timeout--;
    }
}



void bat_down_status2()//100ms
{
    uint8_t transmit_mailbox = 0;
    uint8_t i;
    /* initialize transmit message */
    transmit_message.tx_sfid = 0x0;
    transmit_message.tx_efid = 0x18F102F5;
    transmit_message.tx_ft = CAN_FT_DATA;
    transmit_message.tx_ff = CAN_FF_EXTENDED;
    transmit_message.tx_dlen = 8;
    uint16_t soc = 350;// 586:58.6v
    transmit_message.tx_data[0] = soc & 0xFF; //20C
    transmit_message.tx_data[1] = (soc >> 8) & 0xFF;
    uint16_t soh = 654;//1000: -500 + 1000 = 500A;
    transmit_message.tx_data[2] = (soh) & 0xFF; //0,1,2,3,100
    transmit_message.tx_data[3] = (soh >> 8) & 0xFF;
    uint16_t f_cur = 582;// 586:58.6v
    transmit_message.tx_data[4] = f_cur & 0xFF; //20C
    transmit_message.tx_data[5] = (f_cur >> 8) & 0xFF;
    uint16_t b_cur = 582;//1000: -500 + 1000 = 500A;
    transmit_message.tx_data[6] = (b_cur) & 0xFF; //0,1,2,3,100
    transmit_message.tx_data[7] = (b_cur >> 8) & 0xFF;
#if 1
    log_debug("\r\n can0 transmit data:");

    for(i = 0; i < transmit_message.tx_dlen; i++) {
        log_debug(" %02x", transmit_message.tx_data[i]);
    }

    log_debug("  can send\n");
#endif
    /* transmit message */
    transmit_mailbox = can_message_transmit(&transmit_message);
    /* waiting for transmit completed */
    uint32_t timeout = 0xFFFF;

    while((CAN_TRANSMIT_OK != can_transmit_states(transmit_mailbox))) {
        timeout--;
    }
}

void bat_up_fault()//100ms
{
    uint8_t transmit_mailbox = 0;
    uint8_t i;
    /* initialize transmit message */
    transmit_message.tx_sfid = 0x0;
    transmit_message.tx_efid = 0x18F103F4;
    transmit_message.tx_ft = CAN_FT_DATA;
    transmit_message.tx_ff = CAN_FF_EXTENDED;
    transmit_message.tx_dlen = 8;
    transmit_message.tx_data[0] = 0;
    transmit_message.tx_data[1] = 0;
    transmit_message.tx_data[2] = 0;
    transmit_message.tx_data[3] = 0;
    transmit_message.tx_data[4] = 0;
    transmit_message.tx_data[5] = 0;
    transmit_message.tx_data[6] = 0;
    transmit_message.tx_data[7] = 0;
#if 1
    log_debug("\r\n can0 transmit data:");

    for(i = 0; i < transmit_message.tx_dlen; i++) {
        log_debug(" %02x", transmit_message.tx_data[i]);
    }

    log_debug("  can send\n");
#endif
    /* transmit message */
    transmit_mailbox = can_message_transmit(&transmit_message);
    /* waiting for transmit completed */
    uint32_t timeout = 0xFFFF;

    while((CAN_TRANSMIT_OK != can_transmit_states(transmit_mailbox))) {
        timeout--;
    }
}

void bat_down_fault()//100ms
{
    uint8_t transmit_mailbox = 0;
    uint8_t i;
    /* initialize transmit message */
    transmit_message.tx_sfid = 0x0;
    transmit_message.tx_efid = 0x18F103F5;
    transmit_message.tx_ft = CAN_FT_DATA;
    transmit_message.tx_ff = CAN_FF_EXTENDED;
    transmit_message.tx_dlen = 8;
    transmit_message.tx_data[0] = 0;
    transmit_message.tx_data[1] = 0;
    transmit_message.tx_data[2] = 0;
    transmit_message.tx_data[3] = 0;
    transmit_message.tx_data[4] = 0;
    transmit_message.tx_data[5] = 0;
    transmit_message.tx_data[6] = 1;
    transmit_message.tx_data[7] = 0;
#if 1
    log_debug("\r\n can0 transmit data:");

    for(i = 0; i < transmit_message.tx_dlen; i++) {
        log_debug(" %02x", transmit_message.tx_data[i]);
    }

    log_debug("  can send\n");
#endif
    /* transmit message */
    transmit_mailbox = can_message_transmit(&transmit_message);
    /* waiting for transmit completed */
    uint32_t timeout = 0xFFFF;

    while((CAN_TRANSMIT_OK != can_transmit_states(transmit_mailbox))) {
        timeout--;
    }
}

void mcu_fault()//500ms
{
    uint8_t transmit_mailbox = 0;
    uint8_t i;
    static uint8_t n = 0;
    /* initialize transmit message */
    transmit_message.tx_sfid = 0x0;
    transmit_message.tx_efid = 0x18F0FFC1;
    transmit_message.tx_ft = CAN_FT_DATA;
    transmit_message.tx_ff = CAN_FF_EXTENDED;
    transmit_message.tx_dlen = 8;
    /*if(n == 0) {
        n = 6;

    } else if(n == 6) {
        n = 10;

    } else if(n == 10) {
        n = 11;

    } else if(n == 11) {
        n = 14;

    } else if(n == 14) {
        n = 15;

    } else if(n == 15) {
        n = 18;

    } else if(n == 18) {
        n = 19;

    } else if(n == 19) {
        n = 0;
    }*/
    transmit_message.tx_data[0] = n;//20C
    transmit_message.tx_data[1] = 0;
    transmit_message.tx_data[2] = 0;//0,1,2,3,100
    transmit_message.tx_data[3] = 0;
    transmit_message.tx_data[4] = 0;
    transmit_message.tx_data[5] = 0;
    transmit_message.tx_data[6] = 0;
    transmit_message.tx_data[7] = 0;
#if 1
    log_debug("\r\n can0 transmit data:");

    for(i = 0; i < transmit_message.tx_dlen; i++) {
        log_debug(" %02x", transmit_message.tx_data[i]);
    }

    log_debug("  can send\n");
#endif
    /* transmit message */
    transmit_mailbox = can_message_transmit(&transmit_message);
    /* waiting for transmit completed */
    uint32_t timeout = 0xFFFF;

    while((CAN_TRANSMIT_OK != can_transmit_states(transmit_mailbox))) {
        timeout--;
    }
}
#endif

void can_receive(void)
{
    uint8_t i;
#ifdef TEST_CAN_LINE
#warning("can test")
    static uint8_t b;
#endif

    if(SET == receive_flag) {
        //gd_eval_led_toggle(LED2);
        receive_flag = RESET;
#ifdef TEST_CAN_LINE

        if(b) {
            b = 0;
            LED_ON(187);

        } else {
            b = 1;
            LED_OFF(187);
        }

#endif
#if 1
        log_debug("can0 rec len: %d \n", receive_message.rx_dlen);
        log_debug("sfid:0x%x efid:0x%x\n", receive_message.rx_sfid, receive_message.rx_efid);
        log_debug("rx_ff:0x%x rx_ft:0x%x rx_fi:0x%x\n", receive_message.rx_ff, receive_message.rx_ft, receive_message.rx_fi);

        for(i = 0; i < receive_message.rx_dlen; i++) {
            log_debug(" %02x", receive_message.rx_data[i]);
        }

        log_debug("\n");
#endif

        if(receive_message.rx_efid == 0x18F001C1) {
            log_debug("bat:%d.%dV\n", (receive_message.rx_data[0] << 8 | receive_message.rx_data[1]) / 10, (receive_message.rx_data[0] << 8 | receive_message.rx_data[1]) % 10);
            log_debug("cur:%d.%dA\n", (receive_message.rx_data[2] << 8 | receive_message.rx_data[3]) / 10, (receive_message.rx_data[2] << 8 | receive_message.rx_data[3]) % 10);
            log_debug(" :%d.%dN.m\n", (receive_message.rx_data[4] << 8 | receive_message.rx_data[5]) / 10, (receive_message.rx_data[4] << 8 | receive_message.rx_data[5]) % 10);
            rate_v = (receive_message.rx_data[6] << 8 | receive_message.rx_data[7]);
            //if(pre_rate_v == 0xFFFF) {
            //    pre_rate_v = rate_v;
            //}
            log_debug(" :%drpm\n", rate_v);

        } else if(receive_message.rx_efid == 0x18F002C1) {
            //if(receive_message.rx_data[2]==0)
            ctrl_d = receive_message.rx_data[2];
            ret_status = receive_message.rx_data[4];
            recoil_energy = receive_message.rx_data[3];
            throttle_open = receive_message.rx_data[5];

        } else if(receive_message.rx_efid == 0x18FE20F1) {
            ;//CLEAN
            clear_odo_trip();
            //range_info.mul = 0;

        } else if(receive_message.rx_efid == 0x18F101F4) {//BAT A
            bat_up.vol = receive_message.rx_data[1] << 8 | receive_message.rx_data[0];
            bat_up.cur = receive_message.rx_data[3] << 8 | receive_message.rx_data[2];
            bat_up.sig = receive_message.rx_data[4];
            bat_up.status = receive_message.rx_data[5];
            bat_up.mos = receive_message.rx_data[6];
            bat_up.fault = receive_message.rx_data[7];
            //log_debug("bat up 1 sig %d\n",bat_up.sig&2);

        } else if(receive_message.rx_efid == 0x18F101F5) {//BAT B
            bat_down.vol = receive_message.rx_data[1] << 8 | receive_message.rx_data[0];
            bat_down.cur = receive_message.rx_data[3] << 8 | receive_message.rx_data[2];
            bat_down.sig = receive_message.rx_data[4];
            bat_down.status = receive_message.rx_data[5];
            bat_down.mos = receive_message.rx_data[6];
            bat_down.fault = receive_message.rx_data[7];
            //0x18F101F4

        } else if(receive_message.rx_efid == 0x18F102F4) {//BAT A
            bat_up.soc = receive_message.rx_data[1] << 8 | receive_message.rx_data[0];
            bat_up.soh = receive_message.rx_data[3] << 8 | receive_message.rx_data[2];
            bat_up.disc_cur = receive_message.rx_data[5] << 8 | receive_message.rx_data[4];
            bat_up.feed_cur = receive_message.rx_data[7] << 8 | receive_message.rx_data[6];

        } else if(receive_message.rx_efid == 0x18F102F5) {//BAT B
            bat_down.soc = receive_message.rx_data[1] << 8 | receive_message.rx_data[0];
            bat_down.soh = receive_message.rx_data[3] << 8 | receive_message.rx_data[2];
            bat_down.disc_cur = receive_message.rx_data[5] << 8 | receive_message.rx_data[4];
            bat_down.feed_cur = receive_message.rx_data[7] << 8 | receive_message.rx_data[6];

        } else if(receive_message.rx_efid == 0x18F103F4) {//BAT A
            if(receive_message.rx_data[0] || receive_message.rx_data[1] || receive_message.rx_data[2]
               || receive_message.rx_data[3] || receive_message.rx_data[4] || receive_message.rx_data[5]
              /* || receive_message.rx_data[6] || receive_message.rx_data[7]*/) {
                bat_fault |= 1;

            } else {
                bat_fault &= ~1;
            }

        } else if(receive_message.rx_efid == 0x18F103F5) {//BAT B
            if(receive_message.rx_data[0] || receive_message.rx_data[1] || receive_message.rx_data[2]
               || receive_message.rx_data[3] || receive_message.rx_data[4] || receive_message.rx_data[5]
               /*|| receive_message.rx_data[6] || receive_message.rx_data[7]*/) {
                bat_fault |= 0x10;

            } else {
                bat_fault &= ~0x10;
            }

        } else if(receive_message.rx_efid == 0x18F0FFC1) {//
            if((receive_message.rx_data[0] == 6) || (receive_message.rx_data[0] == 11) || (receive_message.rx_data[0] == 14)
              ) {
                motor_fault = 1;

            } else {
                motor_fault = 0;
            }

            if((receive_message.rx_data[0] == 10) || (receive_message.rx_data[0] == 19)
               || (receive_message.rx_data[0] == 15) || (receive_message.rx_data[0] == 18)
              ) {
                ecu_fault = 1;

            } else {
                ecu_fault = 0;
            }

        } else if(receive_message.rx_efid == 0x18FE10F1) {
            send_version = 2;
            can_send_version0();
        }
    }

    if(send_version == 2) {
        can_send_version1();
        send_version = 0;
    }
}


void can_task_hander(void* pvParameters)
{
    uint32_t i, j;
    uint32_t ff;
    uint32_t can_ok;

    do {
        vTaskDelay(50 / portTICK_RATE_MS);
    } while(boot_display != 2);

    can_params_init();
    vTaskDelay(50 / portTICK_RATE_MS);
    //can_send_data();
#ifdef TEST_CAN_PROTOCOL
/*uint8_t iiii=0;
for(;;) {
	mcu_out1_test(iiii);
	iiii+=10;
	vTaskDelay(50 / portTICK_RATE_MS);
}*/

#warning(" TEST_CAN_PROTOCOL ")
    //mcu_fault();
    for(;;) {
		
	    mcu_out0();
		vTaskDelay(20 / portTICK_RATE_MS);
	    mcu_out1();
		vTaskDelay(20 / portTICK_RATE_MS);
	    //yb_clean();
	    bat_up_status1();
	    vTaskDelay(20 / portTICK_RATE_MS);
	    bat_up_status2();
		vTaskDelay(20 / portTICK_RATE_MS);
	    bat_up_fault();
		vTaskDelay(20 / portTICK_RATE_MS);
	    bat_down_fault();
		vTaskDelay(20 / portTICK_RATE_MS);
	    //mcu_out1();
	    //vTaskDelay(20 / portTICK_RATE_MS);
	    bat_down_status1();
	    vTaskDelay(20 / portTICK_RATE_MS);
	    bat_down_status2();
		vTaskDelay(20 / portTICK_RATE_MS);
	    mcu_fault();
		vTaskDelay(20 / portTICK_RATE_MS);
    //bat_show(0, 0);
    //int8_t n = 0;

    
        //mcu_fault();
        //bat_show(n, 0);
        //bat_show(n, 1);
        //n++;
        //vTaskDelay(500 / portTICK_RATE_MS);
    }

#endif

    for(;;) {
        i = 0;

        while(i++ < 100) {
            if(check_can_time <= CAN_TIMEOUT_L) {
                can_params_init();

            } else {
                can_receive();
            }

            vTaskDelay(5 / portTICK_RATE_MS);
        }

        //if(j++>4){
        //  j=0;
        if(rate_v != 0xFFFF) {
            //if(check_can_time > CAN_TIMEOUT_L) {
            if(rate_v!=0){
            	can_send_data();
            }
        }

        //}

        if(check_can_time) {
            check_can_time--;
        }

#ifdef TASK_PRINT_STACK

        if(ff++ >= 10) {
            ff = 0;
            UBaseType_t remainingStack = uxTaskGetStackHighWaterMark(NULL);
            log_debug("can: %lu(%luB)\n", remainingStack, remainingStack * 4);
        }

#endif
    }
}
uint32_t check_can_time;
void USBD_LP_CAN_RX0_IRQHandler(void)
{
    /* check the receive message */
    //log_debug("can isr %x\n", receive_message.rx_sfid);
    can_message_receive(CAN_FIFO0, &receive_message);
    check_can_time = CAN_TIMEOUT_TIME_H;
    //if((0x7ab == receive_message.rx_sfid)&&(CAN_FF_STANDARD == receive_message.rx_ff) && (8 == receive_message.rx_dlen)){
    receive_flag = SET;
    //}
}
